﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Threading.Tasks;
using Sustainalytics.ClientDW.Synchronization.SyncHbaseData.Handles;
using Sustainalytics.ClientDW.Synchronization.SyncHbaseData.Helpers;
using Sustainalytics.ClientDW.Synchronization.SyncHbaseData.Orchestrators;

namespace Sustainalytics.ClientDW.Synchronization.SyncHbaseData.Tests
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            SetSyncMessages(string.Format("Start at {0} ", DateTime.UtcNow));

            var cddbConnectorConnectionString = ConfigurationManager.ConnectionStrings["MongoDBConnectionString"].ConnectionString;
            var dsoConnectorConnectionString = ConfigurationManager.ConnectionStrings["DSOConnectionString"].ConnectionString;
            var skip = int.Parse(ConfigurationManager.AppSettings["HbaseSkip"]);
            var take = int.Parse(ConfigurationManager.AppSettings["HbaseTake"]);

            var getHbaseData = new GetHbaseData(SetSyncMessages);

            var corporateIdentifierTypeHandler = new CorporateIdentifierTypeHandler(cddbConnectorConnectionString, SetSyncMessages);
            var regionHandler = new RegionHandler(cddbConnectorConnectionString, SetSyncMessages);
            var countryHandler = new CountryHandler(cddbConnectorConnectionString, SetSyncMessages);

            var governaceRegionHandle = new GovernanceRegionHandler(cddbConnectorConnectionString, SetSyncMessages);

            //
            var recreateCollectionOrchestrator = new RecreateCollectionOrchestrator(getHbaseData, corporateIdentifierTypeHandler, regionHandler, governaceRegionHandle, countryHandler, SetSyncMessages);

            recreateCollectionOrchestrator.ProcessData().Wait();
            var generateCompanySearchRecords = new GenerateCompanySearchRecords(new UrlFriendlyGenerator(), corporateIdentifierTypeHandler);

            var companySearchHandle = new CompanySearchHandle(cddbConnectorConnectionString, dsoConnectorConnectionString, generateCompanySearchRecords, SetSyncMessages);
            var handlersByCorporateDetails = new List<IHasRecordsFromHbase>
            {
                new CorporateDataHandler(cddbConnectorConnectionString, SetSyncMessages),
                new FinancialDataHandler(cddbConnectorConnectionString, SetSyncMessages),
                //new CompanySearchHandle(cddbConnectorConnectionString, corporateIdentifierTypeHandler, SetSyncMessages)
            };

            foreach (var handler in handlersByCorporateDetails)
            {
                handler.DropCollectionIndexes().Wait();
            }
            CorporateDataCleanerHandler corporateDataCleanerHandler = new CorporateDataCleanerHandler(cddbConnectorConnectionString, SetSyncMessages);
            var corporateDetailsOrchestrator = new CorporateDetailsOrchestrator(getHbaseData, handlersByCorporateDetails, companySearchHandle, SetSyncMessages, corporateDataCleanerHandler);

            var stopWatch = Stopwatch.StartNew();

            try
            {
                var t1 = Task.Run(async () => await corporateDetailsOrchestrator.ProcessData(skip, take).ConfigureAwait(false));
                t1.Wait();
            }
            catch (Exception exception)
            {
                var exceptionMessages = exception.ToString();

                SetSyncMessages(exceptionMessages);
                throw;
            }

            SetSyncMessages(string.Format("Cleaning STARTED")
            );

            foreach (var handler in handlersByCorporateDetails)
            {
                handler.CreateCollectionIndexes().Wait();
                companySearchHandle.CreateCollectionIndexes().Wait();
                // handler.RemoveCompaniesWithNoPuAsync(idsToDelete).Wait();
            }

            stopWatch.Stop();

            SetSyncMessages(string.Format("COMPLETED at {0} duration {1} ", DateTime.UtcNow, stopWatch.Elapsed));

            Console.ReadKey();
        }

        private static void SetSyncMessages(string message)
        {
            Console.WriteLine(message);
        }
    }

    //var tasks = GetMongoDataHandlersTasks(companies);
    //foreach (var task in tasks)
    //{
    //    task.Start();
    //}
    //companies = getHbaseData.GetCorporateDetails(skip, take);

    //Task.WaitAll(tasks.ToArray());

    //private static void TestAsync()
    //{
    //    var stage = new HBaseRepository("https://cddb.azurehdinsight.net", "admin", "Cddbase2015!");
    //    //var stage = new HBaseRepository("https://susthbase.azurehdinsight.net", "admin", "Susta2015!");
    //    var repo = new CorporateDataRepository(stage);
    //   /*var data= repo.ListCorporateGovernanceRegions();

    //    foreach (var d in data)
    //    {
    //        Console.WriteLine("{0}:{1}",d.Key,d.Value);
    //    }*/
    //    //repo.ListCountriesAndRegions().ToList().ForEach(a=>Console.WriteLine("Id:{0},Name:{1},RegionId:{2}, RegionName:{3}",a.Id,a.Name,a.RegionId,a.RegionName));

    //    var arr = new[] { Guid.Parse("b6eb525c-a764-4b8a-bec0-933a26271fc2") };
    //    var sw = Stopwatch.StartNew();
    //    repo.ListIdentifiersTypes(DateTime.MinValue, DateTime.MaxValue);
    //    var compResult=repo.ListCompanies(DateTime.MinValue, DateTime.MaxValue, Int32.MinValue, Int32.MaxValue).ToList();

    //    using (var sr=new StreamWriter("output3.txt"))
    //    {
    //        compResult.ToList().ForEach(details =>
    //        {
    //            sr.WriteLine(string.Format("CapitalIQID:{0},CompanyId:{1},MainExchange:{2},MainTicker:{3},MainIsin:{4},TotalCount:{5},RegionCode:{6}, RegionName:{7}", details.CapitalIqId, details.CompanyId,
    //                details.MainExchange, details.MainTicker, details.MainIsin, details.TotalCountOfIdentifiers,details.Info.GovernanceRegionCode,details.Info.GovernanceRegionName));
    //        } );
    //    }

    //   var result = repo.ListGlobalAccessIdentifiersOrderedByCompanyId(arr,DateTime.MinValue, DateTime.MaxValue, 0, int.MaxValue);
    //    using (var sr=new StreamWriter("output2.txt"))
    //    {
    //        result.ToList().ForEach(a => sr.WriteLine("MainSecurity:{0} Security:{1} CompanyId:{2},Value:{4}, ValueTypeId:{5},IsMainIdentifier:{3},MainIsin:{6} ",a.MainSecurityId,a.SecurityId,a.CompanyId,a.IsMainIdentifier,a.IdentifierValue,a.IdentifierTypeId,a));

    //    }

    //    Console.WriteLine(result.Count()+" "+sw.Elapsed);
    // //   Console.WriteLine(result.Count(a=>!a.ActiveResearches.Any()));

    //    var skip = 0;
    //    /*while (true)
    //    {
    //        var count = repo.ListGlobalAccessIdentifiersOrderedByCompanyId(arr, DateTime.MinValue, DateTime.MaxValue,
    //            skip, 1000)??new List<CompanyIdentifier>();
    //        if (!count.Any()) break;
    //        Console.WriteLine(count.Count());
    //        skip += 1000;

    //    }
    //    /* try
    //    {
    //        Console.WriteLine("Working at ListIdentifiersTypes");

    //        var resul2 = repo.ListIdentifiersTypes(DateTime.MinValue,DateTime.Now) ?? new Dictionary<string, string>();
    //        foreach (var v in resul2)
    //        {
    //            Console.WriteLine(string.Format("{0}:{1}", v.Key, v.Value));
    //        }
    //        if (!resul2.Any()) Console.WriteLine("No results");
    //        Console.WriteLine(resul2.Count);
    //    }
    //    catch (Exception ex)
    //    {
    //        Console.WriteLine("Exception at ListIdentifiersTypes {0}", ex);
    //    }*/
    //    /*var changedFrom = new DateTime(2015, 1, 1);
    //    // var changedFrom=DateTime.MinValue;
    //    var changedTo = new DateTime(2015, 12, 1);
    //    var skip = 0;
    //    var take = 500;
    //    Console.WriteLine("Changed From: {0}", changedFrom.ToString("d"));
    //    Console.WriteLine("Changed To: {0}", changedTo.ToString("d"));
    //    Console.WriteLine("Skip:{0}", skip);
    //    Console.WriteLine("Take:{0}", take);
    //    Console.WriteLine("Company guids search");
    //    var list = new Guid[]
    //    {
    //        Guid.Parse("6c6845ff-4d9e-4f4d-b920-962af834ef0a"),
    //        Guid.Parse("c63d64c5-013d-4134-a5d2-02873ac759fd"),
    //        Guid.Parse("b0e0cb97-fc7a-4b35-ab01-c83c790a600c")
    //    };
    //    foreach (var guid in list)
    //    {
    //        Console.WriteLine(guid);
    //    }

    //    try
    //    {
    //        var result = repo.ListCompanies(DateTime.MinValue, DateTime.MaxValue, skip, take) ?? new List<CorporateDetails>();
    //        foreach (var corporateDetailse in result)
    //        {
    //            Console.WriteLine("{0} {1}",corporateDetailse.CompanyId,corporateDetailse.MainSecurityId);
    //            if (corporateDetailse.Identifiers.Any(a => a.SecurityId == a.MainSecurityId))
    //            {
    //                Console.WriteLine("MainSecurity found {0}",corporateDetailse.Identifiers.FirstOrDefault(a=>a.SecurityId==a.MainSecurityId).MainSecurityId);
    //            }
    //        }

    //        //Console.WriteLine("Working at ListCompanies");
    //        //var sw = Stopwatch.StartNew();
    //        //while (true)
    //        //{
    //        //    Console.WriteLine("Skip: {0} Take: {1}",skip,take);
    //        //    var result = repo.ListCompanies(DateTime.MinValue, DateTime.MaxValue, skip, take)?? new List<CorporateDetails>();
    //        //    sw.Stop();
    //        //    Console.WriteLine("Time:{0} {1}",sw.Elapsed,result.Count());

    //        //    sw.Reset();
    //        //    sw.Start();
    //        //    skip += take;
    //        //    if (!result.Any())
    //        //    {
    //        //        break;
    //        //    }
    //        //}
    //        //foreach (var corporateDetailse in result)
    //        //{
    //        //    Console.WriteLine(string.Format("{0}-{1}", corporateDetailse.CapitalIqId, corporateDetailse.CompanyId));
    //        //    foreach (var companyIdentifier in corporateDetailse.Identifiers)
    //        //    {
    //        //        Console.WriteLine("{0}->{1}",companyIdentifier.SecurityId,companyIdentifier.MainSecurityId);
    //        //    }
    //        //}
    //        //if (!result.Any()) Console.WriteLine("No results");
    //    }
    //    catch (Exception ex)
    //    {
    //        Console.WriteLine("Exception at :ListCompanies in {0} ", ex.ToString());
    //    }

    //    try
    //    {
    //        Console.WriteLine("Working at ListGlobalAccessIdentifiersOrderedByCompanyId");
    //        var result3 =
    //            repo.ListGlobalAccessIdentifiersOrderedByCompanyId(list, changedFrom, changedTo, skip, take)??new List<CompanyIdentifier>();
    //        foreach (var a in result3.GroupBy(a=>a.CompanyId).Where(a=>a.Any(d=>d.MainSecurityId!=0)))
    //        {
    //            foreach (var v in a)
    //            {
    //                Console.WriteLine("{0}:{1} , {2}", v.CompanyId, v.IdentifierValue, v.IsMainIdentifier);
    //            }

    //        }
    //        if (!result3.Any()) Console.WriteLine("No results");
    //    }
    //    catch (Exception ex)
    //    {
    //        Console.WriteLine("Exception at ListGlobalAccessIdentifiersOrderedByCompanyId {0}", ex);
    //    }

    //    try
    //    {
    //        Console.WriteLine("Working at ListCountries");
    //        var result4 = repo.ListCountries(changedFrom, changedTo)??new List<Country>();
    //        foreach (var country in result4)
    //        {
    //            Console.WriteLine("{0}:{1}", country.Id, country.Name);
    //        }
    //        if (!result4.Any()) Console.WriteLine("No results");
    //    }
    //    catch (Exception e)
    //    {
    //        Console.WriteLine("Exception at ListCountries {0}", e);
    //    }
    //    Console.WriteLine("Press key");
    // */
    //}
}
